package com.googlecode.guicehibernate.interceptor;

import java.io.Serializable;

import org.hibernate.EmptyInterceptor;
import org.hibernate.EntityMode;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.internal.Preconditions;

public class DependencyInjectionInterceptor extends EmptyInterceptor {

	private static final long serialVersionUID = 8905449172276964666L;
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	private Injector injector;

	private final Key<SessionFactory> sessionFactoryKey;

	public DependencyInjectionInterceptor(Key<SessionFactory> sessionFactoryKey) {
		this.sessionFactoryKey = sessionFactoryKey;
	}

	@Override
	public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
		Preconditions.checkNotNull(injector, "Injector not found, please set the injector after container created.");
		SessionFactory sessionFactory = sessionFactory();
		Class<?> clazz = sessionFactory.getClassMetadata(entityName).getMappedClass(entityMode);
		try {
			Object entity = injector.getInstance(clazz);
			sessionFactory.getClassMetadata(entityName).setIdentifier(entity, id, entityMode);
			return entity;
		} catch (Exception e) {
			logger.error("Failed to initialiaze entity via guice, using default behaviour...", e);
			return super.instantiate(entityName, entityMode, id);
		}
	}

	private SessionFactory sessionFactory() {
		return injector.getInstance(sessionFactoryKey);
	}

	public void setInjector(Injector injector) {
		this.injector = injector;
	}

}
